package pers.hl.module_main.publish

import android.graphics.drawable.Drawable
import android.os.Bundle
import android.text.InputType
import android.text.TextUtils
import android.view.View
import android.widget.EditText
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.StringUtils
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import org.simple.eventbus.EventBus
import per.goweii.anylayer.Layer
import pers.hl.common.base.BaseVBVMActivity
import pers.hl.common.base.ext.showMessage
import pers.hl.common.ui.CommonTextWatcher
import pers.hl.common.utils.MyUtils
import pers.hl.lib_global.common.AMapLocateHelper
import pers.hl.lib_global.common.Const
import pers.hl.lib_global.common.MMKVHelper
import pers.hl.lib_global.model.bean.Book
import pers.hl.lib_global.model.bean.BookTag
import pers.hl.lib_global.model.bean.DoubanBook
import pers.hl.lib_global.model.bean.Library
import pers.hl.module_main.CommonEditActivity
import pers.hl.module_main.R
import pers.hl.module_main.common.CommonDialog
import pers.hl.module_main.common.ConfirmDialog
import pers.hl.module_main.common.DrawableUtil
import pers.hl.module_main.common.ScanHelper
import pers.hl.module_main.databinding.ActivityPublishBinding
import java.lang.StringBuilder

class PublishActivity : BaseVBVMActivity<ActivityPublishBinding, PublishViewModel>() {

    private lateinit var publishAdapter: BaseQuickAdapter<CommonEditActivity.EditBean, BaseViewHolder>

    private var mBook = Book()

    private lateinit var tagLayer: Layer
    private lateinit var libLayer: Layer
    private lateinit var noNearByLibLayer: Layer
    private var mDrScan: Drawable? = null
    private var mDrArrow: Drawable? = null

    override fun initView(savedInstanceState: Bundle?) {
        initTitle()
        initRV()
        mDrScan = createBoundsDrawable(R.drawable.ic_qr_scan)
        mDrArrow = createBoundsDrawable(R.drawable.ic_arrow_down)
    }

    private fun createBoundsDrawable(resId: Int): Drawable? {
        val drawable = ContextCompat.getDrawable(mContext, resId)
        drawable?.setBounds(0, 0, 55, 55)
        return drawable
    }

    private fun initTitle() {
        mBinding.apply {
            titleBar.apply {
                tvBarTitle.text = "图书发布"
                ivBarRight.setImageResource(R.drawable.ic_send)
                ivBarRight.setOnClickListener {
                    LogUtils.d("发布书籍：$mBook")
                    if (mBook.bookTag == null) {
                        showMessage("请选择书籍标签")
                        return@setOnClickListener
                    }
                    if (StringUtils.isEmpty(mBook.bookName)) {
                        showMessage("请输入书籍名称")
                        return@setOnClickListener
                    }
                    if (mBook.bookLibId == null) {
                        showMessage("请选择所属图书馆")
                        return@setOnClickListener
                    }
                    mViewModel.publishBook(mBook).observe(this@PublishActivity, Observer {
                        EventBus.getDefault()
                            .post("图书发布成功", Const.MessageEvent.EVENT_BOOK_INFO_CHANGE)
                        showMessage(it)
                        setResult(RESULT_OK)
                        finish()
                    })
                }
                ivBarLeft.setOnClickListener {
                    finish()
                }
            }
        }
    }

    private fun initRV() {
        mBinding.apply {
            rvBookContent.layoutManager = LinearLayoutManager(mContext)
            publishAdapter = object :
                BaseQuickAdapter<CommonEditActivity.EditBean, BaseViewHolder>(R.layout.item_rv_common_edit) {
                override fun convert(holder: BaseViewHolder, item: CommonEditActivity.EditBean) {
                    holder.setText(R.id.tvTitle, item.title)
                    holder.setText(R.id.etContent,  if (TextUtils.isEmpty(item.content)) "" else item.content)
                    holder.setEnabled(R.id.etContent, item.enable)
                    dealSpecialLogic(holder, item)
                }
            }
            rvBookContent.adapter = publishAdapter
        }
    }

    private fun dealSpecialLogic(holder: BaseViewHolder, item: CommonEditActivity.EditBean) {
        val etContent = holder.getView<EditText>(R.id.etContent)
        when (item.tagId) {
            1 -> {
                etContent.isFocusableInTouchMode = false
                etContent.setCompoundDrawables(null, null, mDrArrow, null)
            }
            2 -> {
                etContent.setCompoundDrawables(null, null, mDrScan, null)
                DrawableUtil(etContent).setListener(object : DrawableUtil.OnDrawableListener {

                    override fun onRight(v: View?, right: Drawable?) {
                        ScanHelper.openScanPage(
                            mContext,
                            "请扫描图书条形码",
                            successBlock = { activity, result, format ->
                                val isbnCode =
                                    MyUtils.tryParseLong(result, Const.DEFAULT_BAR_CODE_LONG)
                                if (isbnCode == Const.DEFAULT_BAR_CODE_LONG) {
                                    showMessage("请扫描正确的图书条形码")
                                    return@openScanPage
                                }
                                activity.finish()
                                mViewModel.fetchDouBanInfo(isbnCode)
                                    .observe(this@PublishActivity, Observer {
                                        if (it == null) {
                                            showMessage("未获取到详细信息，请手动填写")
                                            return@Observer
                                        }
                                        LogUtils.d("外层线程:${Thread.currentThread().name}")
                                        fillBookInfo(isbnCode, it)
                                    })
                            })
                    }
                })
            }
            5 -> etContent.inputType = InputType.TYPE_CLASS_NUMBER
            6 -> {
                etContent.isFocusableInTouchMode = false
                etContent.setCompoundDrawables(null, null, mDrArrow, null)
            }
        }
        etContent.setOnClickListener {
            when (item.tagId) {
                1 -> fetchAllTags()
                6 -> fetchNearByLibraries()
            }
        }
//        val llEdit = holder.getView<LinearLayout>(R.id.llEdit)
//        llEdit.setOnClickListener {
//            when (item.tagId) {
//                1 -> fetchAllTags()
//                6 -> fetchNearByLibraries()
//            }
//        }
        val watcher = object : CommonTextWatcher(etContent) {
            override fun textChanged(view: EditText, text: String) {
                when (item.tagId) {
                    2 -> mBook.bookName = text
                    3 -> mBook.bookAuthor = text
                    5 -> mBook.bookIsbn =
                        MyUtils.tryParseLong(text, Const.DEFAULT_BAR_CODE_LONG)
                    7 -> mBook.bookDesc = text
                }
            }
        }

        // 在onBindViewHolder()中通过在适当的时机添加或移除Edittext的TextChangedListener来处理数据错乱的问题。
        // 这个适当的时机就是选在Edittext获得焦点的时候添加监听器，失去焦点的时候再移除监听器，这样可以保证数据的正确性。
        etContent.setOnFocusChangeListener { v, hasFocus ->
            if (hasFocus) {
                etContent.addTextChangedListener(watcher)
            } else {
                etContent.removeTextChangedListener(watcher)
            }
        }
    }

    /**
     * 根据豆瓣api返回填充ui
     */
    private fun fillBookInfo(isbnCode: Long, it: DoubanBook?) {
        it?.apply {
            val etBookName: EditText? = getRvContentView(2)
            val etBookAuthor: EditText? = getRvContentView(3)
            val etBookIsbn: EditText? = getRvContentView(5)
            val etBookDesc: EditText? = getRvContentView(7)

            val author = StringBuilder()
            for (a in it.author) {
                author.append(a)
            }
            mBook.bookName = it.title
            mBook.bookAuthor = author.toString()
            mBook.bookIsbn = isbnCode
            mBook.bookDesc = it.summary
            mBook.bookImg = it.image

            etBookName?.setText(it.title)
            etBookAuthor?.setText(author.toString())
            etBookIsbn?.setText(isbnCode.toString())
            etBookDesc?.setText(it.summary)

        }
    }

    private fun getRvContentView(tagId: Int): EditText? {
         // 减一是因为adapter位置和tagId相差1
        return publishAdapter.getViewByPosition(tagId - 1, R.id.etContent) as EditText?
    }

    /**
     * 获取附近图书馆
     */
    private fun fetchNearByLibraries() {
        val location = MMKVHelper.getCurLocation()
        if (location == null) {
            showMessage("获取定位中，请稍后")
            AMapLocateHelper.getLocation {
                LogUtils.d("保存定位信息：$it")
                MMKVHelper.saveCurLocation(it)
            }
            return
        }
        mViewModel.fetchNearByLibraries(location).observe(this, Observer {
            if (it.isNullOrEmpty()) {
                showNoNearbyLibDialog()
            } else {
                showLibListDialog(it.toMutableList())
            }
        })
    }

    private fun fetchAllTags() {
        mViewModel.getAllTags().observe(this, Observer {
            if (it.isNullOrEmpty()) {
                showMessage("未获取到图书标签信息，请联系管理员")
            } else {
                showTagListDialog(it.toMutableList())
            }
        })
    }

    private fun showNoNearbyLibDialog() {
        noNearByLibLayer = ConfirmDialog.create(this)
            .content("附近没有发现图书馆，是否查找所有图书馆?")
            .setCancelListener { }
            .setConfirmListener {
                mViewModel.getAllLibraries().observe(this, Observer {
                    showLibListDialog(it.toMutableList())
                })
            }
        noNearByLibLayer.show()

    }

    override fun initData(savedInstanceState: Bundle?) {
        // 获取标签
        showBookInfo(mBook)
    }

    private fun showBookInfo(data: Book) {
        data.apply {
            val list = listOf(
                CommonEditActivity.EditBean(1, "标签", tagName.toString()),
                CommonEditActivity.EditBean(2, "书名", bookName.toString()),
                CommonEditActivity.EditBean(3, "作者", bookAuthor.toString()),
                CommonEditActivity.EditBean(
                    4,
                    "发布者",
                    MMKVHelper.getUser()?.userName.toString(),
                    false
                ),
                CommonEditActivity.EditBean(5, "ISBN", bookIsbn.toString()),
                CommonEditActivity.EditBean(6, "图书馆", bookLibStr.toString()),
                CommonEditActivity.EditBean(7, "描述", bookDesc.toString()),
            )
            publishAdapter.addData(list)
        }
    }

    private fun showTagListDialog(tagList: MutableList<BookTag>) {
        tagLayer = CommonDialog.createBottomList(mContext, tagList, convertBlock = { holder, item ->
            holder.getView<TextView>(R.id.tvItem).text = item.name
        }, onItemClick = { layer, adapter, position, item ->
            val etBookTag = getRvContentView(1)
            etBookTag?.setText(item.name.toString())
            mBook.bookTag = item.id
            tagLayer.dismiss()
        })
        tagLayer.show()
    }

    private fun showLibListDialog(libList: MutableList<Library>) {
        libLayer = CommonDialog.createBottomList(mContext, libList, convertBlock = { holder, item ->
            holder.getView<TextView>(R.id.tvItem).text =
                String.format("%s(%sm)", item.libName.toString(), item.distance)
        }, onItemClick = { layer, adapter, position, item ->
            val etContent = getRvContentView(6) as EditText
            etContent.setText(item.libName.toString())
            mBook.bookLibId = item.libId
            libLayer.dismiss()
        })
        libLayer.show()
    }
}